﻿using Furion;
using Furion.Templates;
using SqlSugar;

namespace BootstrapClient.DataAccess.SqlSugar
{
    /// <summary>
    /// 数据库上下文对象
    /// </summary>
    public static class DbContext
    {
        /// <summary>
        /// SqlSugar 数据库实例
        /// </summary>
        public static readonly SqlSugarScope Instance = new(
            // 读取 appsettings.json 中的 ConnectionConfigs 配置节点
            App.GetConfig<List<ConnectionConfig>>("ConnectionConfigs")
            , db =>
            {                
                //单例参数配置，所有上下文生效
                db.Aop.OnLogExecuting = (sql, pars) =>
                {
                    var template = TP.Wrapper("森云科技@SenYun",
                          "森云科技",
                          "提供专业软件开发",
                          "Time:" + DateTime.Now,
                          sql
                        );
                    Console.WriteLine(template);//输出sql
                };


                db.Aop.OnError = ex =>
                {
                    if (ex.Parametres == null) return;
                    var originColor = Console.ForegroundColor;
                    Console.ForegroundColor = ConsoleColor.DarkRed;
                    var pars = db.Utilities.SerializeObject(((SugarParameter[])ex.Parametres).ToDictionary(it => it.ParameterName, it => it.Value));
                    Console.WriteLine("【" + DateTime.Now + "——错误SQL】\r\n" + UtilMethods.GetSqlString(db.CurrentConnectionConfig.DbType, ex.Sql, (SugarParameter[])ex.Parametres) + "\r\n");
                    Console.ForegroundColor = originColor;
                    App.PrintToMiniProfiler("SqlSugar", "Error", $"{ex.Message}{Environment.NewLine}{ex.Sql}{pars}{Environment.NewLine}");
                };

                db.Aop.DataExecuting = (oldValue, entityInfo) =>
                {
                    if (entityInfo.OperationType == DataFilterType.InsertByObject)
                    {
                        // 主键(long类型)且没有值的---赋值雪花Id
                        if (entityInfo.EntityColumnInfo.IsPrimarykey && entityInfo.EntityColumnInfo.PropertyInfo.PropertyType == typeof(long))
                        {
                            var id = entityInfo.EntityColumnInfo.PropertyInfo.GetValue(entityInfo.EntityValue);
                            if (id == null || (long)id == 0)
                                entityInfo.SetValue(SnowFlakeSingle.Instance.NextId());
                        }
                        if (entityInfo.PropertyName == "CreateTime")
                            entityInfo.SetValue(DateTime.Now);

                        if (entityInfo.PropertyName == "CreateUserId")
                        {
                            var createUserId = ((dynamic)entityInfo.EntityValue).CreateUserId;
                            if (createUserId == 0 || createUserId == null)
                                entityInfo.SetValue(App.User?.FindFirst("UserId")?.Value);
                        }
                    }
                    if (entityInfo.OperationType == DataFilterType.UpdateByObject)
                    {
                        if (entityInfo.PropertyName == "UpdateTime")
                            entityInfo.SetValue(DateTime.Now);
                        if (entityInfo.PropertyName == "UpdateUserId")
                            entityInfo.SetValue(App.User?.FindFirst("UserId")?.Value);
                    }
                };

                // 这里配置全局事件，比如拦截执行 SQL
            });
    }
}
